﻿
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
using System.Windows.Media;
using SensorDrone.Net;
using SensorDrone.Net.Extensions;
using SensorDroneStudio.Common;
using SensorDroneStudio.Models;
using SensorDroneStudio.Services;
using SimpleMvvmToolkit;

namespace SensorDroneStudio.ViewModels
{
    public class DroneViewModel : ViewModelDetailBase<DroneViewModel, ISensorDrone>
    {
        private readonly ObservableCollection<SensorViewModel> _sensors;
        private string _address;
        private Color _foreground = Colors.White;
        private bool _ledsOn;
        private string _name;
        private IObservable<Reading> _observable;
        private string _version;

        public DroneViewModel()
        {
            _sensors = new ObservableCollection<SensorViewModel>();
            RegisterToReceiveMessages<ISensorDrone>(MessageTokens.DroneSelected, OnDroneSelected);
            RegisterToReceiveMessages(MessageTokens.Scanning, OnScanning);
            Model = new MockSensorDrone("N/A");
        }

        public string Name
        {
            get { return _name; }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    NotifyPropertyChanged(vm => vm.Name);
                }
            }
        }

        public string Version
        {
            get { return _version; }
            set
            {
                if (_version != value)
                {
                    _version = value;
                    NotifyPropertyChanged(vm => vm.Version);
                }
            }
        }

        public string Address
        {
            get { return _address; }
            set
            {
                if (_address != value)
                {
                    _address = value;
                    NotifyPropertyChanged(vm => vm.Address);
                }
            }
        }

        public ObservableCollection<SensorViewModel> Sensors
        {
            get { return _sensors; }
        }

        public Color Foreground
        {
            get { return _foreground; }
            set
            {
                if (_foreground != value)
                {
                    _foreground = value;
                    NotifyPropertyChanged(vm => vm.Foreground);
                }
            }
        }

        public bool LedsOn
        {
            get { return _ledsOn; }
            set
            {
                if (_ledsOn != value)
                {
                    _ledsOn = value;
                    NotifyPropertyChanged(vm => LedsOn);
                    Led(_ledsOn ? Colors.White : Colors.Black);
                }
            }
        }

        private async void Led(Color color)
        {
            await Model.Leds(color);
        }

        private async void OnDroneSelected(object sender, NotificationEventArgs<ISensorDrone> args)
        {
            if (Model != args.Data)
            {
                Model = args.Data;
                Name = Model.Name;
                Address = Model.Address;
                Version = Model.Version;
                Sensors.Clear();
                await Model.EnableAllAsync();
                List<ISensor> sensors = Model.Sensors.Where(sensor => sensor.IsSi).ToList();
                _observable = Model.AsObservable(sensors.Select(sensor => sensor.Name));
                foreach (ISensor sensor in sensors.Where(sensor => sensor.IsSi))
                {
                    Sensors.Add(new SensorViewModel(_observable.Timestamp(), sensor.Name, new SensorPlotModel()));
                }
                IObservable<Reading> colorObservable = Model.AsObservable(new[] {"RGBC"});
                Sensors.Add(new SensorViewModel(colorObservable.Timestamp(), "RGBC", new ColrorSensorPlotModel()));
            }
        }

        private void OnScanning(object sender, NotificationEventArgs args)
        {
            if (Model != null)
            {
                Model.Leds(Colors.Black);
                Model.Dispose();
            }
            Model = new MockSensorDrone("N/A");
            Name = "";
            Address = "";
            Version = "";
            Sensors.Clear();
        }
    }
}